package com.zyx.concurrentdemo.mytest.c04;

import lombok.extern.slf4j.Slf4j;

/**
 * @author zyx
 * @since 2021/10/16 18:13
 * desc: 基于wait和notify实现数据的顺序打印
 */
@Slf4j(topic = "c.OrderingPrintDemo01")
public class OrderingPrintDemo01 {
    public static void main(String[] args) {
        WaitAndNotify waitAndNotify = new WaitAndNotify(1, 5);
        new Thread(() -> waitAndNotify.run("a", 1, 2), "t1").start();
        new Thread(() -> waitAndNotify.run("b", 2, 3), "t2").start();
        new Thread(() -> waitAndNotify.run("c", 3, 1), "t3").start();
    }

}

class WaitAndNotify {
    /**
     * 等待标记
     */
    private int flag;

    /**
     * 循环次数
     */
    private final int loopNumber;

    public WaitAndNotify(int flag, int loopNumber) {
        this.flag = flag;
        this.loopNumber = loopNumber;
    }

    public void run(String msg, int currentFlag, int nextFlag) {
        for (int i = 0; i < loopNumber; i++) {
            synchronized (this) {
                while (this.flag != currentFlag) {
                    // 等待唤醒
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 唤醒后打印
                System.out.print(msg);
                flag = nextFlag;
                this.notifyAll();
            }
        }
    }
}


